﻿using Microsoft.AspNetCore.SignalR;
using B.S.DataBase.MyProject.Domain.PatientMobileDevice;
using B.S.DataBase.MyProject.Infrastructure;
using Microsoft.AspNetCore.Authorization;
using System.Security.Claims;

namespace MedicalPCTerminal.Write.API
{
    /// <summary>
    /// 处理实时聊天功能的 SignalR Hub
    /// </summary>
    [AllowAnonymous]
    public class ChatHub : Hub
    {
        private readonly SqlSugarContext _sugar;
        private static readonly Dictionary<string, string> _userConnections = new Dictionary<string, string>();
        private static readonly Dictionary<string, int> _userRoles = new Dictionary<string, int>(); // 存储用户角色（1-医生，2-患者）

        /// <summary>
        /// ChatHub 构造函数
        /// </summary>
        /// <param name="sugar">SqlSugar 数据库上下文</param>
        public ChatHub(SqlSugarContext sugar)
        {
            _sugar = sugar;
        }

        /// <summary>
        /// 当用户连接时触发的方法
        /// </summary>
        /// <returns>连接任务</returns>
        public override async Task OnConnectedAsync()
        {
            try
            {
                // 从QueryString获取用户名
                var userName = Context.GetHttpContext()?.Request.Query["userName"].ToString();
                if (string.IsNullOrEmpty(userName))
                {
                    userName = Context.ConnectionId;
                }
                _userConnections[userName] = Context.ConnectionId;

                await Clients.Caller.SendAsync("Connected", new { ConnectionId = Context.ConnectionId, UserName = userName });
                await base.OnConnectedAsync();
            }
            catch
            {
                await base.OnConnectedAsync();
            }
        }

        /// <summary>
        /// 当用户断开连接时触发的方法
        /// </summary>
        /// <param name="exception">断开连接的异常信息</param>
        /// <returns>断开连接任务</returns>
        public override async Task OnDisconnectedAsync(Exception? exception)
        {
            var userName = Context.GetHttpContext()?.Request.Query["userName"].ToString();
            if (!string.IsNullOrEmpty(userName) && _userConnections.ContainsKey(userName))
            {
                _userConnections.Remove(userName);
            }
            await base.OnDisconnectedAsync(exception);
        }

        /// <summary>
        /// 发送私聊消息
        /// </summary>
        /// <param name="receiverUserName">接收者用户名</param>
        /// <param name="message">消息内容</param>
        /// <returns>发送消息任务</returns>
        public async Task SendPrivateMessage(string receiverUserName, string message)
        {
            try
            {
                // 发送者用户名
                var senderUserName = Context.GetHttpContext()?.Request.Query["userName"].ToString();
                if (string.IsNullOrEmpty(senderUserName))
                {
                    senderUserName = Context.ConnectionId;
                }

                // 保存到数据库
                var chatMessage = new ChatListItem
                {
                    Sender = senderUserName,
                    ContactName = receiverUserName,
                    ChatMessage = message,
                    MessageContent = message,
                    ChatTime = DateTime.Now,
                    HasRedDot = true,
                    IsDel = false,
                    // 你可以根据业务设置Role/ContactRole
                };
                await _sugar.db.Insertable(chatMessage).ExecuteCommandAsync();

                // 推送给接收方
                if (_userConnections.TryGetValue(receiverUserName, out string? connectionId))
                {
                    await Clients.Client(connectionId).SendAsync("ReceivePrivateMessage", new
                    {
                        Sender = senderUserName,
                        Message = message,
                        ChatTime = chatMessage.ChatTime
                    });
                }

                // 推送给自己（发送成功提示）
                await Clients.Caller.SendAsync("MessageSent", new
                {
                    Success = true,
                    Message = "消息已发送",
                    ChatTime = chatMessage.ChatTime
                });
            }
            catch (Exception ex)
            {
                await Clients.Caller.SendAsync("Error", new { Message = $"发送消息失败: {ex.Message}" });
            }
        }

        /// <summary>
        /// 标记消息为已读
        /// </summary>
        /// <param name="messageId">聊天消息ID</param>
        /// <returns>标记已读任务</returns>
        public async Task MarkMessageAsRead(int messageId)
        {
            try
            {
                await _sugar.db.Updateable<ChatListItem>()
                    .SetColumns(x => new ChatListItem { HasRedDot = false })
                    .Where(x => x.ChatListItemID == messageId)
                    .ExecuteCommandAsync();
                    
                await Clients.Caller.SendAsync("MessageMarkedAsRead", new { MessageId = messageId });
            }
            catch (Exception ex)
            {
                await Clients.Caller.SendAsync("Error", new { Message = $"标记消息已读失败: {ex.Message}" });
            }
        }

        /// <summary>
        /// 获取与指定用户的聊天历史
        /// </summary>
        /// <param name="otherUserName">对方用户名</param>
        /// <returns>获取聊天历史任务</returns>
        public async Task GetChatHistory(string otherUserName)
        {
            try
            {
                var currentUserName = Context.GetHttpContext()?.Request.Query["userName"].ToString();
                
                // 如果没有用户名，使用连接ID
                if (string.IsNullOrEmpty(currentUserName))
                {
                    currentUserName = Context.ConnectionId;
                }
                
                var messages = await _sugar.db.Queryable<ChatListItem>()
                    .Where(x => !x.IsDel &&
                               ((x.Sender == currentUserName && x.ContactName == otherUserName) || 
                                (x.Sender == otherUserName && x.ContactName == currentUserName)))
                    .OrderBy(x => x.ChatTime)
                    .ToListAsync();

                // 将未读消息标记为已读
                var unreadMessages = messages.Where(x => x.Sender == otherUserName && 
                                                     x.ContactName == currentUserName && 
                                                     x.HasRedDot).ToList();
                if (unreadMessages.Any())
                {
                    foreach (var msg in unreadMessages)
                    {
                        msg.HasRedDot = false;
                    }
                    
                    await _sugar.db.Updateable(unreadMessages)
                        .UpdateColumns(x => new { x.HasRedDot })
                        .ExecuteCommandAsync();
                }
                
                await Clients.Caller.SendAsync("ChatHistory", messages);
            }
            catch (Exception ex)
            {
                await Clients.Caller.SendAsync("Error", new { Message = $"获取聊天历史失败: {ex.Message}" });
            }
        }

        /// <summary>
        /// 获取未读消息数量
        /// </summary>
        /// <returns>未读消息数量任务</returns>
        public async Task GetUnreadMessagesCount()
        {
            try
            {
                var currentUserName = Context.GetHttpContext()?.Request.Query["userName"].ToString();
                
                // 如果没有用户名，使用连接ID
                if (string.IsNullOrEmpty(currentUserName))
                {
                    currentUserName = Context.ConnectionId;
                    await Clients.Caller.SendAsync("UnreadMessagesCount", 0);
                    return;
                }
                
                var count = await _sugar.db.Queryable<ChatListItem>()
                    .Where(x => !x.IsDel && x.ContactName == currentUserName && x.HasRedDot)
                    .CountAsync();
                
                await Clients.Caller.SendAsync("UnreadMessagesCount", count);
            }
            catch (Exception ex)
            {
                await Clients.Caller.SendAsync("Error", new { Message = $"获取未读消息数量失败: {ex.Message}" });
            }
        }
    }
}
